package com.tanjun.publicservice.web.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.tanjun.common.exception.BizException;
import com.tanjun.publicservice.web.orm.entity.SysDictData;
import com.tanjun.publicservice.web.orm.mapper.SysDictDataMapper;
import com.tanjun.publicservice.web.service.SysDictDataService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author tanjun
* @description 针对表【sys_dict_data(字典数据表)】的数据库操作Service实现
* @createDate 2025-01-09 21:42:04
*/
@Service
public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDictData>
    implements SysDictDataService{

    /**
     * 新增或者修改字典数据
     *
     * @param dictCode 字典编码
     * @param list     字典数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = {"listDictDataByCode"},allEntries = true)
    public void saveOrUpdateDictDaraList(String dictCode, List<SysDictData> list) {
        if(CollectionUtil.isEmpty(list)){ //字典数据为空
            this.remove(QueryChain.of(SysDictData.class)
                    .eq(SysDictData::getDictCode,dictCode));
            return;
        }
       //判断本次保存字典数据中是否存在相同值
        if(list.stream().map(SysDictData::getValue).distinct().count()!=list.size()){
            throw new BizException("字典数据值不能重复");
        }

        List<SysDictData> listOld=this.list(QueryChain.of(SysDictData.class)
                .eq(SysDictData::getDictCode,dictCode)
        );

        Map<String,SysDictData> mapNew=list.stream().collect(Collectors.toMap(SysDictData::getValue, Function.identity()));
        //计算删除的数据
        List<SysDictData> listDel=listOld.stream()
                .filter(t->!mapNew.containsKey(t.getValue()))
                .collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(listDel)){
            this.removeByIds(listDel.stream().map(SysDictData::getId).collect(Collectors.toList()));
        }
        //计算更新的数据
        List<SysDictData> listUpdate=listOld.stream()
                .filter(t-> {
                            SysDictData sysDictData = mapNew.get(t.getValue());
                            return sysDictData != null;
                        }
                )
                .collect(Collectors.toList());
        if(!listUpdate.isEmpty()){
            listUpdate.forEach(d->{
                SysDictData sysDictData = mapNew.get(d.getValue());
                sysDictData.setId(d.getId());
                sysDictData.setDictCode(dictCode);
                this.updateById(sysDictData);
            });
        }
        //计算插入的数据
        List<String> listOldValue=listOld.stream().map(SysDictData::getValue).collect(Collectors.toList());
        List<SysDictData> listInsert=list.stream().filter(t->!listOldValue.contains(t.getValue())).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(listInsert)){
            listInsert.forEach(d->{
                d.setUpdater(null);
                d.setUpdateTime(null);
                d.setDictCode(dictCode);
                d.setId(null);
                this.save(d);
            });
        }
    }

    /**
     * 删除字典数据
     *
     * @param dictCode 字典编码
     */
    @Override
    @CacheEvict(cacheNames = {"listDictDataByCode"},allEntries = true)
    public void delDictData(String dictCode) {
        this.remove(QueryChain.of(SysDictData.class)
                .eq(SysDictData::getDictCode,dictCode)
        );
    }

    /**
     * 根据编码 获取所有的字典数据
     *
     * @param dictCode 字典编码
     * @return 字典数据
     */
    @Override
    @Cacheable(value = "listDictDataByCode")
    public List<SysDictData> listDictDataByCode(String dictCode) {
        return this.list(QueryChain.of(SysDictData.class)
                .eq(SysDictData::getDictCode,dictCode)
                .orderBy(SysDictData::getSort)
                .asc()
        );
    }
}




